package reflection;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * Created with IntelliJ IDEA
 * Description:反射速度对比优化
 * User:22954
 * Date:2024-04-12
 * Time:14:13
 */
public class Compare {
    /*
    反射调用速度比直接调用速度慢许多
    setAccessible(boolean flag) 是启用和禁用访问安全检查的开关
        flag = true 表示反射对象在使用时取消访问检查,能提高反射效率,但效果不明显
    Method/Field/Constructor都继承AccessibleObject,均可调用setAccessible
     */
    public static void main(String[] args) throws ClassNotFoundException, InvocationTargetException, IllegalAccessException, InstantiationException, NoSuchMethodException {
        m1();
        m2();
        m3();
    }

    public static void m1() {
        Cat cat = new Cat();
        long start = System.currentTimeMillis();
        for (int i = 0; i < 90000000; i++) {
            cat.move();
        }
        long end = System.currentTimeMillis();
        System.out.println("m1() = " + (end - start));//5
    }

    public static void m2() throws InvocationTargetException, IllegalAccessException, InstantiationException, NoSuchMethodException, ClassNotFoundException {
        Class<?> aClass = Class.forName("reflection.Cat");
        Method method = aClass.getMethod("move");
        Object o = aClass.getDeclaredConstructor().newInstance();
        long start = System.currentTimeMillis();
        for (int i = 0; i < 90000000; i++) {
            method.invoke(o);
        }
        long end = System.currentTimeMillis();
        System.out.println("m2() = " + (end - start));//375
    }
    public static void m3() throws InvocationTargetException, IllegalAccessException, InstantiationException, NoSuchMethodException, ClassNotFoundException {
        Class<?> aClass = Class.forName("reflection.Cat");
        Method method = aClass.getMethod("move");
        Object o = aClass.getDeclaredConstructor().newInstance();
        method.setAccessible(true);
        long start = System.currentTimeMillis();
        for (int i = 0; i < 90000000; i++) {
            method.invoke(o);
        }
        long end = System.currentTimeMillis();
        System.out.println("m3() = " + (end - start));//294
    }
}
